在現代的系統開發中,前後端分離與API 設計幾乎已經成為必備的基礎觀念。本文將以我們的 Vue 銷售系統為例,說明什麼是前後端分離、API 的角色,以及如何一步一步從介面設計推導出清晰的 API 規劃。
前後端分離簡單來說,就是讓「前端」與「後端」各自專注於自己的職責,並透過 API 互相溝通:
前端 (Frontend)
例如我們正在開發的 Vue 應用程式,負責 使用者看得到、摸得到的介面與互動。
後端 (Backend)
伺服器端程式,負責 業務邏輯、資料庫操作、資料的儲存。
API (Application Programming Interface) 的功能,就像一座「橋樑」:
沒有 API,前後端就無法有效地協作。
設計 API 的第一步,就是觀察系統的每一個頁面,並問自己:
「這個頁面需要『看』什麼資料?」
→ 決定我們需要哪些 GET API。
「使用者可以在這個頁面『做』什麼事?」
→ 決定我們需要哪些 POST、PUT、DELETE API。
這種方式可以讓我們的 API 與實際需求緊密結合,避免冗餘設計。
這邊我們以客戶管理的這個介面來設計我們所需要的 API 有哪些
對應 API:
GET /customers/search?keyword=xxx
→ 根據關鍵字搜尋客戶GET /customers
→ 取得客戶列表GET /customers/{id}
→ 取得單一客戶詳細資料POST /customers
→ 新增客戶PUT /customers/{id}
→ 更新客戶資料DELETE /customers/{id}
→ 刪除客戶在系統開發中,前端和後端需要約定好「溝通的規則」,否則可能會出現很多問題。
1. 前後端能夠順利溝通
前端要知道後端回傳的資料長什麼樣子,才能正確顯示給使用者。
後端也要知道前端傳來的資料結構,才能正確處理請求。
2. 維護與擴充容易
如果每個 API 回傳的格式都不一樣,未來加新功能時就會非常容易出錯。
統一格式後,前端可以寫「通用的資料處理程式」,不必為每個 API 寫不同邏輯。
方便處理成功與失敗情況,且統一的回傳結構可以讓前端快速判斷操作是否成功,並顯示相應訊息。
資料格式:統一使用 JSON
。
回應結構:
success:表示這次 API 操作是否成功
data:成功時真正的資料放在這裡
error:失敗時提供錯誤資訊,包括錯誤碼與訊息
成功回應:
{
"success": true,
"data": { ... }
}
失敗回應:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "錯誤訊息"
}
}
在 Vue 中,API 通常不會直接寫在模板裡,而是透過 封裝的函式或服務 去呼叫。這樣做的好處:
統一管理 API:所有請求集中在同一個檔案或資料夾,方便維護。
減少重複程式碼:前端組件不需要重複寫 fetch 或 axios 邏輯。
方便處理錯誤與統一格式:統一處理 API 成功、失敗回傳,前端可以快速判斷並顯示訊息。
// api/customers.js
import axios from 'axios';
const BASE_URL = 'https://your-api.com';
export const getCustomers = () => axios.get(`${BASE_URL}/customers`);
export const getCustomerById = (id) => axios.get(`${BASE_URL}/customers/${id}`);
export const createCustomer = (data) => axios.post(`${BASE_URL}/customers`, data);
export const updateCustomer = (id, data) => axios.put(`${BASE_URL}/customers/${id}`, data);
export const deleteCustomer = (id) => axios.delete(`${BASE_URL}/customers/${id}`);
<template>
<div>
<ul>
<li v-for="customer in customers" :key="customer.id">{{ customer.name }}</li>
</ul>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import { getCustomers } from '@/api/customers';
export default {
setup() {
const customers = ref([]);
onMounted(async () => {
try {
const response = await getCustomers();
if (response.data.success) {
customers.value = response.data.data;
}
} catch (error) {
console.error('API 錯誤', error);
}
});
return { customers };
}
};
</script>
對於多個組件共用資料(如報價單、客戶列表),可以使用我們前面提過的 Pinia
// store/customers.js (Pinia)
import { defineStore } from 'pinia';
import { getCustomers } from '@/api/customers';
export const useCustomerStore = defineStore('customer', {
state: () => ({
customers: [],
}),
actions: {
async fetchCustomers() {
const response = await getCustomers();
if (response.data.success) this.customers = response.data.data;
}
}
});
在組件中只需要:
const customerStore = useCustomerStore();
await customerStore.fetchCustomers();
這樣組件就可以只顯示資料,不處理 API 邏輯,方便多組件共享狀態。
今天,我們完整地將前後端分離與 API 設計的概念,從觀察使用者介面出發,應用到我們的 銷售系統中。
判斷資料需求 → 明確知道每個頁面需要哪些資料(GET API)。
定義使用者操作 → 決定使用者可以執行哪些動作(POST、PUT、DELETE API)。
封裝 API → 將系統功能對應到清晰、易懂的 API 端點,並統一管理。
在 Vue 中使用 → 組件只專注顯示資料,API 呼叫由封裝函式或全域狀態管理處理。
統一資料格式與回應規範 → 使用 JSON 統一回傳結構,方便前端快速處理成功與失敗情況。
明日,我們將進入 Day 6:[Vueの呼吸・伍之型] Vue基礎 - 響應式原理與實作,了解 Vue 的響應式原理。 心を燃やせ !!